﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IO = System.IO;
using System.Windows;
using System.Windows.Threading;
using System.Xml.Serialization;
using System.IO.Compression;
using System.Text.RegularExpressions;

namespace MsiCustomize
{
    public static class Extensions
    {
        /// <summary>
        /// Empty delegate for ForceRender and DoEvents
        /// </summary>
        private static System.Action EmptyDelegate = delegate () { };

        /// <summary>
        /// Replacement for WinForms DoEvents
        /// </summary>
        /// <param name="Source">Application</param>
        public static void DoEvents(this Application Source)
        {
            Source.Dispatcher.Invoke(DispatcherPriority.Background, EmptyDelegate);
        }

        /// <summary>
        /// Force a render even inside a loop        
        /// </summary>
        /// <param name="VisualElement"></param>
        public static void ForceRender(this System.Windows.UIElement VisualElement)
        {
            VisualElement.UpdateLayout();
            VisualElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
        }

        /// <summary>
        /// Generic Compressed XML Serializer Save Array
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="SourceData">Serializable object to be stored</param>
        /// <param name="FileName">FileName to save as</param>
        public static void Save<T>(this T SourceData, string FileName)
        {
            IO.Directory.CreateDirectory(IO.Path.GetDirectoryName(FileName));
            IO.Stream TargetData = new IO.MemoryStream();
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            IO.FileStream TargetFile = new IO.FileStream(FileName, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.Read);
            TargetData = new GZipStream(TargetFile, CompressionMode.Compress);
            IO.TextWriter writer = new IO.StreamWriter(TargetData);
            serializer.Serialize(writer, SourceData);
            writer.Flush();
            writer.Close();
            TargetFile.Close();
        }

        /// <summary>
        /// Generic Compressed XML Serializer Load Array
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="FileName">Filename to read</param>
        /// <returns>Data object of type T</returns>
        public static dynamic Load<T>(string FileName)
        {
            IO.Stream SourceData = null;
            object Data = new object();
            if (IO.File.Exists(FileName))
            {
                SourceData = new GZipStream(
                    new IO.FileStream(FileName, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.ReadWrite),
                    CompressionMode.Decompress);
                XmlSerializer deserializer = new XmlSerializer(typeof(T));
                IO.TextReader reader = new IO.StreamReader(SourceData);
                Data = deserializer.Deserialize(reader);
                reader.Close();
            }
            return (T)Data;
        }

        /// <summary>
        /// Allows for Wild Card string matching
        /// </summary>
        /// <param name="Text">String to be checked</param>
        /// <param name="pattern">Pattern or mask to be checked against</param>
        /// <param name="IsCaseSensitive">Is this match Case Sensitive?</param>
        /// <returns></returns>
        public static bool IsLike(this string Text, string pattern, bool IsCaseSensitive = false)
        {
            pattern = pattern.Replace(".", @"\.").Replace("?", ".").Replace("*", ".*?").Replace(@"\", @"\\").Replace(" ", @"\s");
            return new Regex(pattern, IsCaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase).IsMatch(Text);
        }
    }
}
